# -*- coding: UTF-8 -*-
# @create  : 2024/8/30 10:42
# @Author  : 天空之城
# @File    : tokenize_and_normalize_route.py
from flask import jsonify

from address_normalizer.app.common.params import RequestBase
from address_normalizer.app.common.response import InvalidAddressError, AddressParameterError, RF, EF
from address_normalizer.app.config import logger, TOKENIZE_MODEL, PROVINCE_CITY_DISTRICT
from address_normalizer.app.models.address_model import AddressModel
from address_normalizer.app.models.corrector import CorrectAddress
from address_normalizer.app.models.invalid_address import InvalidAddress
from address_normalizer.app.models.location_model import LocationModel
from address_normalizer.app.schemas.address_schemas import InvalidAddressSchemas, AddressSchemas


class TokenizeAddress(RequestBase):

    def post(self):
        """
        正确地址的分词与验证：
        切分到省级： 部分正确的地址需要准确切分到省级。
        地址验证与补全： 验证地址正确性，并在必要时补全信息。

        错误地址的处理：
        提示信息返回： 对错误地址提供明确的提示信息。
        区分错误地址与部分正确地址： 需要有效区分错误地址和部分正确地址的机制。
        数据维护：

        地址数据更新： 提供的地址数据可能变动，需要定期维护。
        代码逻辑：
        先进行分词，对每个词性进行判断，如果词性为地名，则进行地址验证与补全。
        如果不存在地名，则返回错误信息。
        :return:
        """
        original_address = self.get_param('Address')
        logger.info(f"————————接收地址信息：{original_address}————————")
        original_address = LocationModel.preprocess_address(original_address)
        # 无效地址判断
        address = InvalidAddress().is_valid_address(original_address)
        if InvalidAddressError.Message == address or AddressParameterError.Message == address:
            logger.warning(f"无效地址：{original_address}")
            invalid = InvalidAddressSchemas()
            invalid.invalid_address = original_address
            return EF.error_address(Msg=address, StandardAddress=invalid.dict())
            # 地址纠正与补全
        model = AddressModel()
        predicted_result = model.predict(address)
        address_schemas = AddressSchemas(**predicted_result)

        if sum(x is None for x in (address_schemas.province, address_schemas.city, address_schemas.district)) >= 2:
            model.mode = 'rule'
            predicted_result = model.predict(address)
            address_schemas = AddressSchemas(**predicted_result)

        logger.info(f'地址预测结果{address_schemas}')

        # 根据区补全查找不到的内容
        province, city, district = LocationModel.find_location(
            address_schemas.province,
            address_schemas.city,
            address_schemas.district,
            reference_data=LocationModel.read_csv(PROVINCE_CITY_DISTRICT)
        )
        logger.info(f'根据区补全查到内容：{province, city, district}')
        if sum(x is None for x in (province, city, district)) >= 2:
            logger.warning(f"疑似无效地址：{original_address}")
            invalid = InvalidAddressSchemas()
            invalid.invalid_address = original_address
            return EF.error_address(Msg='查询失败！未获取有效城市信息！', StandardAddress=invalid.dict())
        address_schemas.province, address_schemas.city, address_schemas.district = province, city, district

        # 提取其他地址信息并更新预测结果
        correct = CorrectAddress()
        address_schemas.other_address = correct.extract_other_address(address, result=predicted_result,
                                                                      address_tuple=(province, city, district))
        # 处理标准化地址并更新预测结果
        address_schemas.standard_address = model.standard_address_process(address_schemas)

        # 对于省市区对不上的进行提示
        is_address_correct = LocationModel.check_location(
            address_schemas.province,
            address_schemas.city,
            address_schemas.district,
            reference_data=LocationModel.read_csv(PROVINCE_CITY_DISTRICT)
        )
        if not is_address_correct:
            logger.warning(f"原地址：{original_address},实际地址：{address_schemas},消息提示：省市区对应不上！")
            address_schemas.region_correct = False
        logger.info(f"模型预测结果返回内容: {address_schemas}")
        return RF.success_address(StandardAddress=address_schemas.dict())

    def get(self):
        return self.post()
